﻿using System;
using System.IO;
using System.Text;
using System.Threading;

namespace Kz.Telegram.Bot.Infrastructure.Helpers
{
    /// <summary>
    /// 自定义日志输出到指定文件
    /// </summary>
    /// <remarks>
    /// 带读写锁
    /// </remarks>
    public class LogFileHelper
    {
        private static string Dire = Path.Combine(Directory.GetCurrentDirectory(), "logs");
        private static readonly ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();

        /// <summary>
        /// 信息日志
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="filename"></param>
        /// <param name="log"></param>
        public static void INF(string tag, string filename, string log)
        {
            var dt = DateTime.Now;
            var _dire = Path.Combine(Dire, $"{dt:yyyy-MM-dd}");
            var _file = Path.Combine(_dire, $"{filename}_I.log");

            if (!Directory.Exists(_dire))
            {
                Directory.CreateDirectory(_dire);
            }
            try
            {
                LogWriteLock.EnterWriteLock();

                var temp = $"[{dt:HH:mm:ss.fff}] {tag} , {log} {Environment.NewLine}";
                Console.WriteLine(temp);
                File.AppendAllText(_file, temp);
            }
            catch (Exception)
            {

            }
            finally
            {
                LogWriteLock.ExitWriteLock();
            }
        }

        /// <summary>
        /// 警告日志
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="filename"></param>
        /// <param name="log"></param>
        public static void WAR(string tag, string filename, string log)
        {
            var dt = DateTime.Now;
            var _dire = Path.Combine(Dire, $"{dt:yyyy-MM-dd}");
            var _file = Path.Combine(_dire, $"{filename}_W.log");

            if (!Directory.Exists(_dire))
            {
                Directory.CreateDirectory(_dire);
            }
            try
            {
                LogWriteLock.EnterWriteLock();

                var temp = $"[{dt:HH:mm:ss.fff}] {tag} , {log} {Environment.NewLine}";
                Console.WriteLine(temp);
                File.AppendAllText(_file, temp);
            }
            catch (Exception)
            {

            }
            finally
            {
                LogWriteLock.ExitWriteLock();
            }
        }

        /// <summary>
        /// 错误日志
        /// </summary>
        /// <param name="class"></param>
        /// <param name="method"></param>
        /// <param name="filename"></param>
        /// <param name="log"></param>
        /// <param name="ex"></param>
        public static void ERR(string @class, string filename, string log, Exception ex = null)
        {
            ERR(@class, filename, string.Empty, log, ex);
        }

        /// <summary>
        /// 错误日志
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="method"></param>
        /// <param name="filename"></param>
        /// <param name="log"></param>
        /// <param name="ex"></param>
        public static void ERR(string tag, string filename, string method, string log, Exception ex)
        {
            var dt = DateTime.Now;
            var _dire = Path.Combine(Dire, $"{dt:yyyy-MM-dd}");
            var _file = Path.Combine(_dire, $"{filename}_E.log");

            if (!Directory.Exists(_dire))
            {
                Directory.CreateDirectory(_dire);
            }

            try
            {
                LogWriteLock.EnterWriteLock();

                StringBuilder sb = new StringBuilder(Environment.NewLine);
                sb.AppendLine($"{dt:HH:mm:ss.fff} >  日志:");
                if (!string.IsNullOrEmpty(method))
                {
                    sb.AppendLine($"{dt:HH:mm:ss} >  方法:{method}");
                }
                sb.AppendLine($"                 ------- 异常 -------");
                sb.Append(Environment.NewLine);

                if (ex != null)
                {
                    sb.AppendLine($"{dt:HH:mm:ss} > 【异常类型】 {ex.GetType().Name}");
                    sb.AppendLine($"{dt:HH:mm:ss} > 【异常信息】 {ex.Message}");
                    sb.AppendLine($"{dt:HH:mm:ss} > 【异常对象】 {ex.Source}");
                    sb.AppendLine($"{dt:HH:mm:ss} > 【调用堆栈】 {ex.StackTrace}");
                    sb.AppendLine($"{dt:HH:mm:ss} > 【触发方法】 {ex.TargetSite}");
                }

                Console.WriteLine(sb.ToString());
                File.AppendAllText(_file, sb.ToString());
                sb.Clear();
            }
            catch (Exception)
            {

            }
            finally
            {
                LogWriteLock.ExitWriteLock();
            }
        }
    }
}